home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-11-17 | 17.0 KB | 665 lines | [TEXT/MPS ] |
- /*
-
- Blackout.c - A simple screen fader that runs as a MultiFinder
- application. Is typically launched by Lunarmobiscuit's
- Darkness MultiFinder screen saver program.
-
- copyright © 1989 by Tom Dowdy
- All rights reserved
-
- Modifications
- Aug 5 1989 TED basic fade working as standalone code
- Nov 30 1989 TED file converted to a standalone application
-
- Assumptions:
- MultiFinder is present.
-
- Slightly questionables:
- Uses lowMem mBarHeight for setting menu bar height to 0.
- Modifies a window's visRgn to include the menu bar.
-
-
- */
-
- // Standard MacIncludes - you might wish to use a dump file for this
- #include <Limits.h>
- #include <Types.h>
- #include <Resources.h>
- #include <QuickDraw.h>
- #include <Fonts.h>
- #include <Events.h>
- #include <Windows.h>
- #include <Menus.h>
- #include <TextEdit.h>
- #include <Dialogs.h>
- #include <Desk.h>
- #include <ToolUtils.h>
- #include <Memory.h>
- #include <SegLoad.h>
- #include <Devices.h>
- #include <Files.h>
- #include <OSUtils.h>
- #include <OSEvents.h>
- #include <Traps.h>
- #include <SysEqu.h>
- #include <Script.h>
- #include <Picker.h>
- #include <FixMath.h>
- #include <Packages.h>
- #include <Math.h>
- #include <Palette.h>
- #include <QDOffscreen.h>
- #include <DeskBus.h>
- #include <StdLib.h>
- #include <StdArg.h>
- #include <Strings.h>
- #include <StdIO.h>
-
- // Defines to let this include work okay
- #define INMAINBLACKOUT
- typedef Handle BlackoutHandle;
-
- #include "Blackout.h"
-
-
- /* ------------------------------------------------------------------------------------ */
- /* INTERNAL ROUTINES - Shouldn't need to be changed by Blackout authors. */
- /* ------------------------------------------------------------------------------------ */
- #define mBarHeight (short *)0x0BAA // Low mem global for menu bar
- #define kOSEvent app4Evt // event used by MultiFinder
- #define kSuspendResumeMessage 1 // high byte of suspend/resume event message
- #define kResumeMask 1 // bit of message field for resume vs. suspend
-
- #define TopLeft(aRect) (* (Point *) &(aRect).top)
- #define BotRight(aRect) (* (Point *) &(aRect).bottom)
-
-
- /* This routine is part of the MPW runtime library. This external
- reference to it is done so that we can unload its segment, %A5Init. */
- extern void _DataInit();
-
- SysEnvRec theEnvirons;
- Boolean gHas32BitQD;
-
- /* ------------------------------------------------------------------------------------ */
- #pragma segment Main
-
- void PlaceRectOnScreen(
- short width, // width of rect, can be 0
- short height, // height of rect, can be 0
- Rect * placedRect, // Placed rect is returned here
- Rect * margins, // margins around screen, can be nil
- Rect * screenBound) // placed screen bounds returned here, can be nil
- {
- Rect screenRect;
- short deviceCount;
- GDHandle theDevice;
-
- if (theEnvirons.hasColorQD)
- {
- // First, count the GDevices
- deviceCount = 0;
- theDevice = GetDeviceList();
- while (theDevice != nil)
- {
- if ( (TestDeviceAttribute(theDevice, screenDevice)) &&
- (TestDeviceAttribute(theDevice, screenActive)) )
- deviceCount++;
- theDevice = GetNextDevice(theDevice);
- }
-
- // Then pick one at random
- deviceCount = Rnd(deviceCount)+1;
-
- // Fetch that GDevice
- theDevice = GetDeviceList();
- while (deviceCount != 0)
- {
- if ( (TestDeviceAttribute(theDevice, screenDevice)) &&
- (TestDeviceAttribute(theDevice, screenActive)) )
- {
- deviceCount--;
- if (deviceCount == 0)
- screenRect = (**theDevice).gdRect;
- }
- theDevice = GetNextDevice(theDevice);
- }
-
- }
- else
- screenRect = (**GetGrayRgn()).rgnBBox;
-
- // Localize the points
- GlobalToLocal(&TopLeft(screenRect));
- GlobalToLocal(&BotRight(screenRect));
-
- if (margins != nil)
- {
- screenRect.top += margins->top;
- screenRect.left += margins->left;
- screenRect.bottom -= margins->bottom;
- screenRect.right -= margins->right;
- }
- if (screenBound != nil)
- *screenBound = screenRect;
-
- screenRect.right -= width;
- screenRect.bottom -= height;
-
- placedRect->top = screenRect.top + Rnd(screenRect.bottom - screenRect.top);
- placedRect->left = screenRect.left + Rnd(screenRect.right - screenRect.left);
- placedRect->bottom = placedRect->top + height;
- placedRect->right = placedRect->left + width;
-
- } // PlaceRectOnScreen
-
- /* ------------------------------------------------------------------------------------ */
- #pragma segment Main
-
- short Rnd(long max)
- {
- long value;
-
- value = max * Random();
- if (value < 0)
- value = -value;
- value /= 32767;
- if (value == max)
- value--;
- return(value);
-
- } // Rnd
-
- /* ------------------------------------------------------------------------------------ */
- #pragma segment Main
-
- void AddMenuBarIntoVisRgn(WindowPtr theWindow, short oldMenuBarHeight)
- {
- RgnHandle mBarRgn;
- Rect mBarRect;
-
- /* At this point, our new window doesn't include the menu bar,
- so make a region out of the menu bar, and add it onto
- the window's visRgn */
- mBarRgn = NewRgn();
- if (mBarRgn != nil)
- {
- /* Calculate the rect of the menu bar */
- mBarRect = qd.screenBits.bounds;
- mBarRect.bottom = mBarRect.top + oldMenuBarHeight;
-
- /* ScreenBit is in global, vis regions are local */
- GlobalToLocal(&TopLeft(mBarRect));
- GlobalToLocal(&BotRight(mBarRect));
-
- /* Make a region out of the menu bar */
- RectRgn(mBarRgn, &mBarRect);
-
- /* Tack this region onto the visRgn */
- UnionRgn(theWindow->visRgn, mBarRgn, theWindow->visRgn);
-
- /* Get rid of our temp region */
- DisposeRgn(mBarRgn);
- } // mBarRgn != nil
-
- } // AddMenuBarIntoVisRgn
-
- /* ------------------------------------------------------------------------------------ */
- /* OFFSCREEN PIXMAP UTILTIES */
- /* ------------------------------------------------------------------------------------ */
- void MyDisposeGWorld (GWorldPtr offscreenGWorld);
-
- #pragma segment Initialize
-
- void MyNewGWorld(GWorldPtr *offscreenGWorld,short PixelDepth,Rect *boundsRect,
- CTabHandle cTable,GDHandle aGDevice,GWorldFlags flags)
- {
- long offRowBytes, sizeOfOff;
- Ptr myBits;
- GrafPtr curPort;
- GDHandle oldDevice;
- CTabHandle ourCMHandle;
- short i;
-
- GetPort(&curPort);
-
- gHas32BitQD = false;
- if (theEnvirons.hasColorQD)
- {
- if (NGetTrapAddress (0xAB03, ToolTrap) != NGetTrapAddress (0xA89F, ToolTrap))
- gHas32BitQD = true;
- }
-
- if (gHas32BitQD)
- {
- if (NewGWorld (offscreenGWorld, PixelDepth, boundsRect, cTable, nil, flags) != noErr)
- *offscreenGWorld = nil;
- return;
- }
- else
- {
- *offscreenGWorld = (GWorldPtr) NewPtr(sizeof(CGrafPort));
- if (*offscreenGWorld == nil)
- return;
-
- if (theEnvirons.hasColorQD)
- {
- oldDevice = GetGDevice();
- if (aGDevice != nil)
- SetGDevice(aGDevice);
- OpenCPort((CGrafPtr) *offscreenGWorld);
- }
- else
- {
- OpenPort((GrafPtr) *offscreenGWorld);
- }
-
- offRowBytes = ((((PixelDepth * (RectWidth(boundsRect))) + 15)) / 16) * 2;
- sizeOfOff = ((long) RectHeight(boundsRect)) * offRowBytes;
- myBits = NewPtr(sizeOfOff);
-
- if (myBits == nil)
- {
- MyDisposeGWorld(*offscreenGWorld);
- *offscreenGWorld = nil;
- goto cleanUp;
- }
-
- if (theEnvirons.hasColorQD)
- {
- (** ((CGrafPtr) *offscreenGWorld)->portPixMap).baseAddr = myBits;
- (** ((CGrafPtr) *offscreenGWorld)->portPixMap).rowBytes = offRowBytes + 0x8000;
- (** ((CGrafPtr) *offscreenGWorld)->portPixMap).bounds = *boundsRect;
- (** ((CGrafPtr) *offscreenGWorld)->portPixMap).pmTable = nil;
-
- // and clone that color table!
- ourCMHandle = (**(**aGDevice).gdPMap).pmTable;
- if (HandToHand( &(Handle) ourCMHandle) == noErr)
- {
- for (i = 0; i <= (**ourCMHandle).ctSize; ++i)
- (**ourCMHandle).ctTable[i].value = i;
- (**ourCMHandle).ctFlags &= 0x7fff;
- offRowBytes = GetCTSeed();
- (**ourCMHandle).ctSeed = offRowBytes;
- (** ((CGrafPtr) *offscreenGWorld)->portPixMap).pmTable = ourCMHandle;
- }
- else
- {
- MyDisposeGWorld(*offscreenGWorld);
- *offscreenGWorld = nil;
- goto cleanUp;
- }
-
- }
- else
- {
- ((GrafPtr) *offscreenGWorld)->portBits.baseAddr = myBits;
- ((GrafPtr) *offscreenGWorld)->portBits.rowBytes = offRowBytes;
- ((GrafPtr) *offscreenGWorld)->portBits.bounds = *boundsRect;
- }
- }
-
- cleanUp:
- SetPort(curPort);
- if (theEnvirons.hasColorQD)
- SetGDevice(oldDevice);
-
- return;
- }
-
- /* ------------------------------------------------------------------------------------ */
- #pragma segment Terminate
-
- void MyDisposeGWorld (GWorldPtr offscreenGWorld)
- {
- if (offscreenGWorld != nil)
- if (gHas32BitQD)
- {
- DisposeGWorld(offscreenGWorld);
- }
- else
- {
- if (theEnvirons.hasColorQD)
- {
- CloseCPort((CGrafPtr) offscreenGWorld);
- if ( (** ((CGrafPtr) offscreenGWorld)->portPixMap).pmTable != nil)
- DisposHandle((Handle) (** ((CGrafPtr) offscreenGWorld)->portPixMap).pmTable);
- }
- else
- ClosePort((GrafPtr) offscreenGWorld);
-
- if ((Ptr) ((GrafPtr) offscreenGWorld)->portBits.baseAddr != nil)
- DisposPtr((Ptr) ((GrafPtr) offscreenGWorld)->portBits.baseAddr);
- DisposPtr((Ptr) offscreenGWorld);
- }
- }
-
- /* ------------------------------------------------------------------------------------ */
- #pragma segment Main
-
- void MySetGWorld(GWorldPtr offscreenGWorld)
- {
- if (offscreenGWorld != nil)
- {
- if (gHas32BitQD)
- SetGWorld (offscreenGWorld, nil);
- else
- SetPort((GrafPtr) offscreenGWorld);
- }
- }
- /* ------------------------------------------------------------------------------------ */
- #pragma segment Main
-
- void MyLockPixels(GWorldPtr offscreenGWorld)
- {
- if (offscreenGWorld != nil)
- if (gHas32BitQD)
- LockPixels (offscreenGWorld->portPixMap);
- }
- /* ------------------------------------------------------------------------------------ */
- #pragma segment Main
-
- void MyUnlockPixels(GWorldPtr offscreenGWorld)
- {
- if (offscreenGWorld != nil)
- if (gHas32BitQD)
- UnlockPixels (offscreenGWorld->portPixMap);
- }
-
- /* ------------------------------------------------------------------------------------ */
- /* ------------------------------------------------------------------------------------ */
- #pragma segment Main
-
- void AppleShareDialogs(Boolean turnOn)
- {
- #define AFPSetAlertState 247
- #define DontShowAlerts 1
- #define DoShowAlerts 0
- #define AFPTransRefNum -42
-
- short csParam[11]; /*operation-defined parameters*/
- short anErr;
-
- if (turnOn)
- csParam[1] = DoShowAlerts;
- else
- csParam[0] = DontShowAlerts;
-
- (void) Control(AFPTransRefNum,AFPSetAlertState,(Ptr)csParam);
-
- } // AppleShareDialogs
-
- /* ------------------------------------------------------------------------------------ */
- #pragma segment Initialize
-
- WindowPtr CreateBigWindow(short oldMenuBarHeight)
- {
- Rect theRect;
- RgnHandle theGrayRgn;
- WindowPtr theWindow;
-
- /* Get the full size of the desktop */
- theGrayRgn = GetGrayRgn();
-
- /* Get the bounding box for the gray region */
- theRect = (**theGrayRgn).rgnBBox;
-
- /* Add on the screenbits.bounds, which will include the menu bar */
- UnionRect(&theRect, &qd.screenBits.bounds, &theRect);
-
- /* Make a big window of this size */
- if (theEnvirons.hasColorQD)
- theWindow = NewCWindow(nil, &theRect, "\p", true,
- plainDBox, (WindowPtr) -1, false, 0);
- else
- theWindow = NewWindow(nil, &theRect, "\p", true,
- plainDBox, (WindowPtr) -1, false, 0);
-
- /* If got the window okay, time to modify the visRgn */
- if (theWindow != nil)
- {
- /* Set port to it */
- SetPort(theWindow);
-
- AddMenuBarIntoVisRgn(theWindow, oldMenuBarHeight);
- } // theWindow != nil
-
- return(theWindow);
-
- } // CreateBigWindow
-
- /* ------------------------------------------------------------------------------------ */
- /* PRIVATE GLOBAL AREA */
- /* ------------------------------------------------------------------------------------ */
- // Misc variables
- short gOldMenuBarHeight; // For restoring the old menu bar
- short gCount; // Misc loop variable
-
- // State information for the Blackout effect that is in use
- WindowPtr gBlackoutWindow;
- Handle gTheBlackout;
- long gMinSleepTime;
- long gMaxSleepTime;
- long gSleepTime;
- Boolean gHaveBlackout;
-
- // Variables to keep track of events and when to terminate the application
- Point gOldMouse;
- short gOldModifiers;
- long gOldTime;
- Boolean gContinueRunning;
- EventRecord gTheEvent;
- /* ------------------------------------------------------------------------------------ */
- #pragma segment Initialize
-
- void Initialize()
- {
- unsigned long aSeed;
-
- UnloadSeg((Ptr) _DataInit); /* note that _DataInit must not be in Main! */
-
- MaxApplZone(); /* expand the heap so code segments load at the top */
-
- /* Initialize the toolbox */
- InitGraf((Ptr) &qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
-
- // Seed the random number generator
- GetDateTime(&aSeed);
- qd.randSeed = aSeed;
-
- /* We need a menu or MultiFinder will drop into Macsbug. In addition, it
- should be a File:Quit menu so that MultiFinder can shut us down via
- a puppet string. */
- InsertMenu(GetMenu(1), 0);
- DrawMenuBar();
-
- /* Get our application to the front */
- for (gCount = 1; gCount <= 4; ++gCount)
- EventAvail(everyEvent, &gTheEvent);
-
- /* Turn off AppleShare dialogs */
- AppleShareDialogs(false);
-
- /* Save away the old menu bar height and set it to zero */
- gOldMenuBarHeight = GetMBarHeight();
- *mBarHeight = 0;
-
- /* Find out if we have color QuickDraw */
- SysEnvirons(1, &theEnvirons);
-
- gMinSleepTime = 0;
- gMaxSleepTime = 1;
- gSleepTime = 1;
- gTheBlackout = PreflightBlackout(&gMinSleepTime, &gMaxSleepTime);
-
- gBlackoutWindow = CreateBigWindow(gOldMenuBarHeight);
- if (gBlackoutWindow != nil)
- {
- /* Get the initial mouse position in globals */
- GetMouse(&gOldMouse);
- LocalToGlobal(&gOldMouse);
-
- /* Get the initial modifier keys */
- gOldModifiers = gTheEvent.modifiers & (cmdKey + shiftKey + optionKey + controlKey + alphaLock);
-
- /* Hide the cursor from people */
- HideCursor();
-
- gOldTime = TickCount();
-
- gHaveBlackout = false;
- gContinueRunning = true;
- }
-
- } // Initialize
-
- /* ------------------------------------------------------------------------------------ */
- #pragma segment Main
-
- main()
- {
- long timer;
-
- Initialize();
- UnloadSeg((Ptr) Initialize);
-
- if (gBlackoutWindow != nil)
- {
-
- do
- {
- timer = -TickCount();
- WaitNextEvent(everyEvent, &gTheEvent, gSleepTime, nil);
- timer += TickCount();
-
- if (timer > gSleepTime)
- gSleepTime = timer;
- else
- gSleepTime--;
-
- if (gSleepTime < gMinSleepTime)
- gSleepTime = gMinSleepTime;
- else
- if (gSleepTime > gMaxSleepTime)
- gSleepTime = gMaxSleepTime;
-
- if (! BlackoutEvent(&gTheEvent))
- {
- /* Abort if mouse moved */
- if ((gTheEvent.where.h != gOldMouse.h) ||
- (gTheEvent.where.v != gOldMouse.v))
- gContinueRunning = false;
-
-
- /* Abort if modifiers are down */
- if ((gTheEvent.modifiers & (cmdKey + shiftKey + optionKey + controlKey + alphaLock)) != gOldModifiers)
- {
- gOldModifiers = 0;
-
- if (gTheEvent.modifiers & (cmdKey + shiftKey + optionKey + controlKey + alphaLock))
- gContinueRunning = false;
- }
-
- switch (gTheEvent.what)
- {
- /* Abort if user event */
- case keyDown:
- case autoKey:
- case mouseDown:
- case mouseUp:
- case diskEvt:
- gContinueRunning = false;
- break;
-
- /* If update event, clean out the update */
- case updateEvt:
- BeginUpdate((WindowPtr) gTheEvent.message);
- EndUpdate((WindowPtr) gTheEvent.message);
- break;
-
- /* Activate means window has come to front */
- case activateEvt:
- if (!gHaveBlackout)
- {
- /* Make sure Menu bar is part of the window */
- AddMenuBarIntoVisRgn(gBlackoutWindow, gOldMenuBarHeight);
-
- /* restore previous menu bar height, for notification manager */
- *mBarHeight = gOldMenuBarHeight;
-
- gHaveBlackout = true;
-
- /* Start up the screen saver */
- gContinueRunning = InitBlackout(gTheBlackout, gBlackoutWindow);
-
- /* Get the initial mouse position in globals in case the init causes a
- move of the mouse for the OK button of a dialog or something. */
- GetMouse(&gOldMouse);
- LocalToGlobal(&gOldMouse);
-
- /* Make the mouse invisible until moved */
- ObscureCursor();
- }
- break;
-
- /* If a suspend event, Abort */
- case kOSEvent:
- switch (gTheEvent.message >> 24) { /* high byte of message */
- case kSuspendResumeMessage:
- if ((gTheEvent.message & kResumeMask) == 0)
- gContinueRunning = false;
- break;
- }
- break;
-
- default:
- break;
-
- } // switch(gTheEvent.what)
-
- } // ! BlackoutEvent
-
-
- if ((gHaveBlackout) && (gContinueRunning))
- {
- /* Give the Blackout some time */
- BlackoutIdle(gBlackoutWindow, gTheBlackout);
-
- /* Make sure the cursor is hidden every 10 seconds, if visible (MPW is fond of doing this to us) */
- if (gOldTime <= gTheEvent.when)
- {
- ObscureCursor();
- gOldTime = TickCount() + 600;
- }
- }
-
- UnloadSeg((Ptr) Initialize);
-
- } while (gContinueRunning);
-
- if (gHaveBlackout)
- {
- /* Close down the screen saver */
- DisposeBlackout(gTheBlackout);
- }
-
- /* Get rid of our window */
- DisposeWindow(gBlackoutWindow);
-
- /* Show the cursor to the nice people */
- ShowCursor();
- }
-
- /* Restore previous menu bar height */
- DrawMenuBar();
-
- /* Turn on AppleShare dialogs */
- AppleShareDialogs(true);
-
- } // main